package com.liting.uitest.imgutils;

import com.liting.uitest.model.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 视觉感知强度计算
 */
public class VisionIntensionUtils {
    private final static double r1 = 0.017455;
    private final static double r2 = 0.087489;
    private final static double r3 = 0.158384;
    private final static double r4 = 0.230868;
    private final static double r5 = 0.305731;

    /**
     * 获取5个半径的长
     *
     * @param lenth
     * @return
     */
    public static BigDecimal[] getRlist(double lenth) {
        BigDecimal[] rList = new BigDecimal[5];
        rList[0] = new BigDecimal(r1).multiply(new BigDecimal(lenth)).setScale(6, RoundingMode.HALF_UP);
        rList[1] = new BigDecimal(r2).multiply(new BigDecimal(lenth)).setScale(6, RoundingMode.HALF_UP);
        rList[2] = new BigDecimal(r3).multiply(new BigDecimal(lenth)).setScale(6, RoundingMode.HALF_UP);
        rList[3] = new BigDecimal(r4).multiply(new BigDecimal(lenth)).setScale(6, RoundingMode.HALF_UP);
        rList[4] = new BigDecimal(r5).multiply(new BigDecimal(lenth)).setScale(6, RoundingMode.HALF_UP);

        return rList;
    }

    /**
     * 获取正方形的边长
     *
     * @param r
     * @return
     */
    public static BigDecimal getSideLenth(BigDecimal r) {
        return new BigDecimal(Math.sqrt(Math.PI)).multiply(r);
    }

    /**
     * 获取每个模块的重要度
     *
     * @param moduleImportList
     * @param rectList
     * @param cirList
     * @return
     */
    public static Map<String, Double> getImportInfo(List<ModuleImport> moduleImportList, List<Rectangle> rectList, List<Circle> cirList) {
        Map<String, Double> result = new HashMap<>();
        for (Rectangle rectangle : rectList) {
            result.put(rectangle.getName(), 0.5);
        }
        for (Circle circle : cirList) {
            result.put(circle.getName(), 0.5);
        }

        for (ModuleImport moduleImport : moduleImportList) {

            if (moduleImport.getCompareType() == ModuleImport.CompareType_Same) {
                Double temp1 = result.get(moduleImport.getLeftModuleName());
                temp1 = temp1 + 0.5;

                result.put(moduleImport.getLeftModuleName(), temp1);

                Double temp2 = result.get(moduleImport.getRightModuleName());
                temp2 = temp2 + 0.5;

                result.put(moduleImport.getRightModuleName(), temp2);
            }

            if (moduleImport.getCompareType() == ModuleImport.CompareType_LeftBigger) {
                Double temp1 = result.get(moduleImport.getLeftModuleName());
                temp1 = temp1 + 1;

                result.put(moduleImport.getLeftModuleName(), temp1);
            }

            if (moduleImport.getCompareType() == ModuleImport.CompareType_RightBigger) {
                Double temp1 = result.get(moduleImport.getRightModuleName());
                temp1 = temp1 + 1;

                result.put(moduleImport.getRightModuleName(), temp1);
            }
        }

        return result;

    }


    /**
     * 根据距离或者正方形的视觉强度等级
     *
     * @param distance
     * @param rList
     * @return
     */
    private static int getGrade(double distance, BigDecimal[] rList) {
        if (distance <= rList[0].doubleValue()) {
            return VisionIntentSquare.Vision_Grade_First;
        } else if (distance <= rList[1].doubleValue()) {
            return VisionIntentSquare.Vision_Grade_Second;
        } else if (distance <= rList[2].doubleValue()) {
            return VisionIntentSquare.Vision_Grade_Third;
        } else if (distance <= rList[3].doubleValue()) {
            return VisionIntentSquare.Vision_Grade_Forth;
        } else if (distance <= rList[4].doubleValue()) {
            return VisionIntentSquare.Vision_Grade_Fifth;
        } else {
            return VisionIntentSquare.Vision_Grade_Sixth;
        }
    }

    private static double twoPointLen(double x1, double y1, double x2, double y2) {
        BigDecimal xDistance = new BigDecimal(x1).subtract(new BigDecimal(x2)).abs();
        BigDecimal yDistance = new BigDecimal(y1).subtract(new BigDecimal(y2)).abs();

        BigDecimal temp = xDistance.multiply(xDistance).add(yDistance.multiply(yDistance));

        double distance = Math.sqrt(temp.doubleValue());

        return distance;
    }

//    /**
//     * 每个矩形包括的各个级别的正方形的数量
//     * @param rectangle  矩形信息
//     * @param squareAggreGation  正方形的所有信息
//     * @return Map的key是级别，value是正方形数量
//     */
//    public static Map<Integer, Integer> createRectGradeSquareMap(Rectangle rectangle, VisionIntentSquareAggreGation squareAggreGation) {
//
//        Double[] minMaxXY=findMinMaxXY(rectangle,squareAggreGation);
//
//
//
//        Double beginCenterX=minMaxXY[0],beginCenterY=minMaxXY[1],endCenterX=minMaxXY[2],endCenterY=minMaxXY[3];
//
//
//        Map<VisionIntentSquare,Integer> squreGradeMap=squareAggreGation.getSqureGradeMap();
//        Map<Integer, Integer> result=new HashMap<>();
//
//        for(double i=beginCenterX;i<=endCenterX;i=i+squareAggreGation.getSquareSide()){
//            for(double j=beginCenterY;j<=endCenterY;j=j+squareAggreGation.getSquareSide()){
//                VisionIntentSquare temp=new VisionIntentSquare(
//                        new BigDecimal(i).setScale(6,RoundingMode.UP),
//                        new BigDecimal(j).setScale(6,RoundingMode.UP),
//                        0,new BigDecimal(squareAggreGation.getSquareSide()));
//                Integer grade=squreGradeMap.get(temp);
//
//                Integer count=result.get(grade);
//                if(count==null){
//                    count=0;
//                }
//                count++;
//                result.put(grade,count);
//            }
//        }
//
//        return result;
//    }
//
//    /**
//     * 每个圆形包括的各个级别的正方形的数量
//     * @param circle  圆形信息
//     * @param squareAggreGation  正方形的所有信息
//     * @return Map的key是级别，value是正方形数量
//     */
//    public static Map<Integer, Integer> createCircleradeSquareMap(Circle circle, VisionIntentSquareAggreGation squareAggreGation){
//        //1. 取得圆形的外切矩形
//        Rectangle rectangle=new Rectangle();
//        rectangle.setHeight(circle.getRadius()*2);
//        rectangle.setWidth(circle.getRadius()*2);
//        rectangle.setLeftTopX(circle.getCenterX()-circle.getRadius());
//        rectangle.setLeftTopY(circle.getCenterY()-circle.getRadius());
//
//        //2. 如同createRectGradeSquareMap，获得beginCenterX,beginCenterY,endCenterX,endCenterY
//        Double[] minMaxXY=findMinMaxXY(rectangle,squareAggreGation);
//        Double beginCenterX=minMaxXY[0],beginCenterY=minMaxXY[1],endCenterX=minMaxXY[2],endCenterY=minMaxXY[3];
//
//        //3. 循环，判断每个中旬到圆心的距离是否小于圆的半径，小于计算，大于不包括
//        Map<VisionIntentSquare,Integer> squreGradeMap=squareAggreGation.getSqureGradeMap();
//        Map<Integer, Integer> result=new HashMap<>();
//
//        for(double i=beginCenterX;i<=endCenterX;i=i+squareAggreGation.getSquareSide()){
//            for(double j=beginCenterY;j<=endCenterY;j=j+squareAggreGation.getSquareSide()){
//                double distance=twoPointLen(i,j,circle.getCenterX(),circle.getCenterY());
//                if(distance < circle.getRadius()){
//                    VisionIntentSquare temp=new VisionIntentSquare(
//                            new BigDecimal(i).setScale(6,RoundingMode.UP),
//                            new BigDecimal(j).setScale(6,RoundingMode.UP),
//                            0,new BigDecimal(squareAggreGation.getSquareSide()));
//                    Integer grade=squreGradeMap.get(temp);
//
//                    Integer count=result.get(grade);
//                    if(count==null){
//                        count=0;
//                    }
//                    count++;
//                    result.put(grade,count);
//                }
//
//            }
//        }
//        return result;
//    }

    /**
     * 根据每个模块的重要程度、每个模块包括的不同等级的正方形个数，算视觉强度
     *
     * @param moduleImport    每个模块的重要程度
     * @param moduleSquareMap 每个模块的重要程度
     * @return
     */
    public static BigDecimal calcVisionIntent(Map<String, Double> moduleImport, Map<String, Map<Integer, Integer>> moduleSquareMap) {
        BigDecimal result = new BigDecimal(0);
        for (String moduleName : moduleImport.keySet()) {
            Double importance = moduleImport.get(moduleName);
            Map<Integer, Integer> temp = moduleSquareMap.get(moduleName);

            for (Integer grade : temp.keySet()) {
                Integer count = temp.get(grade);
                Double calcSum = count * grade * importance;
                result = result.add(new BigDecimal(calcSum));
            }
        }
        return result.setScale(2, RoundingMode.UP);
    }

    private static Double findClosest(Set<Double> set, double target) {
        if (set.isEmpty()) return null;

        Double closest = null;
        double minDistance = Integer.MAX_VALUE;

        for (Double element : set) {
            double distance = Math.abs(element - target);
            if (distance < minDistance) {
                minDistance = distance;
                closest = element;
            }
        }

        return closest;
    }

//    private static Double[] findMinMaxXY(Rectangle rectangle, VisionIntentSquareAggreGation squareAggreGation){
//        Double closeMinCenterX=findClosest(squareAggreGation.getCenterXSet(), rectangle.getLeftTopX());
//        Double closeMinCenterY=findClosest(squareAggreGation.getCenterYSet(),rectangle.getLeftTopY());
//        Double closeMaxCenterX=findClosest(squareAggreGation.getCenterXSet(),rectangle.getLeftTopX()+rectangle.getWidth());
//        Double closeMaxCenterY=findClosest(squareAggreGation.getCenterYSet(),rectangle.getLeftTopY()+rectangle.getHeight());
//
//        Double beginCenterX,beginCenterY,endCenterX,endCenterY;
//        if(closeMinCenterX < rectangle.getLeftTopX()){
//            beginCenterX=closeMinCenterX+squareAggreGation.getSquareSide();
//        }else{
//            beginCenterX=closeMinCenterX;
//        }
//        if(closeMinCenterY < rectangle.getLeftTopY()){
//            beginCenterY=closeMinCenterY+squareAggreGation.getSquareSide();
//        }else{
//            beginCenterY=closeMinCenterY;
//        }
//        if(closeMaxCenterX < rectangle.getLeftTopX()+rectangle.getWidth()){
//            endCenterX=closeMaxCenterX;
//        }else{
//            endCenterX=closeMaxCenterX-squareAggreGation.getSquareSide();
//        }
//        if(closeMaxCenterY < rectangle.getLeftTopY()+rectangle.getHeight()){
//            endCenterY=closeMaxCenterY;
//        }else{
//            endCenterY=closeMaxCenterY-squareAggreGation.getSquareSide();
//        }
//        Double[] result=new Double[4];
//        result[0]=beginCenterX;
//        result[1]=beginCenterY;
//        result[2]=endCenterX;
//        result[3]=endCenterY;
//
//        return result;
//    }
}
